package com.zwjstudy.cachestudy.springcache.caffeine.service.impl;

import com.zwjstudy.cachestudy.springcache.caffeine.entity.User;
import com.zwjstudy.cachestudy.springcache.caffeine.service.UserService;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import java.util.Random;

/**
 * ClassName: UserServieImpl
 * Package: com.zwjstudy.cachestudy.springcache.caffeine.service.impl
 * Description:
 *
 * 在分布式集群模式下：
 * 所有的更新操作，全部需要使用分布式锁
 *
 * @Author: 张文俊
 * @Create: 2025-09-20 - 9:43
 * @Version: v1.0
 */
@Service
@CacheConfig(cacheNames = "userCache",cacheManager = "userCacheManager")
public class UserServieImpl implements UserService {


    @CachePut(key ="#user.id",condition = "#user!=null",unless = "#result==null")
    //如果使用springCache缓存数据，key的生成:userCache:
    // 返回值的id进行设置key
    // 推荐：先更新数据库，然后失效缓存（失效模式）
    //@Transactional   //解决缓存一致性问题
    public User save(User user){
        //存储user
        System.out.println("存储："+user);
        return user;
    }

    /**
     * 双写模式：
     * 使用 @CachePut 更新缓存（双写模式，需注意并发问题）
     * @param user
     * @return
     */
    @CachePut(key ="#user.id",condition = "#user!=null",unless = "#result==null")
    //@Transactional   //解决缓存一致性问题
    public User update(User user){
        //更新user
        System.out.println("更新："+user);
        return user;
    }

    /**
     * 推荐：失效模式：
     * 先更新数据库，然后失效缓存（失效模式）
     * @return
     */
    //@CacheEvict(key ="#user.id",condition = "#user!=null",unless = "#result==null") // 方法执行成功后，清除指定key的缓存
    //@Transactional   //解决缓存一致性问题
//    public User update(User user){
//        //更新user
//        System.out.println("更新："+user);
//        return user;
//    }


    @CacheEvict(key="#id")
    //@Transactional   //解决缓存一致性问题
    public void deleteById(Long id){

        System.out.println("删除用户："+id);

    }


    @CacheEvict(allEntries = true)
    //@Transactional   //解决缓存一致性问题
    public void deleteAll(){

        System.out.println("删除所有用户");

    }

    /**
     * sync = true：解决缓存击穿问题，都是对于集群环境需要使用分布式锁
     * sync和unless不共存，使用了sync（true）,不能设置 unless（不生效）
     *
     * @param id
     * @return
     */
    @Cacheable(key="#id",unless = "#result == null")
    //key的生成:userCache:id value:为查询相应的数据，若是查询到，直接进行返回，如果查询不到，则将其加入到缓存
    public User getById(Long id){

        //解决缓存穿透
        if(id==null || id<0 || id>10000){
            return null;
        }

        int i = new Random().nextInt(100);

        User user=new User(id,"zs","zs address"+i);

        System.out.println("加载最新的用户数据到缓存中:"+user);

        return user;
    }

}
